package com.car.slave.im;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import com.car.slave.im.util.IMHeartbeatTool;
import com.car.slave.im.util.IMTool;
import com.car.slave.im.util.InterruptThread;
import com.car.slave.im.util.IMHeartbeatTool.OffLineCallback;

/**
 * IM的后台服务.
 * @author zhangliucheng
 *
 */
public class IMService extends Service implements OffLineCallback {
	
	private enum ConnectState {
		CONNECTING,		// 连接中
		CONNECTED,		// 已连接
		OFFLINE			// 断开连接
	}
	private ConnectState connectState;
	
	private boolean isRunning;		// 服务是否运行
	
	private IMHeartbeatTool heartbeatTool;
	
	private ConnectThread connectThread;
	private ReadThread readThread;
	private WriteThread writeThread;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		isRunning = true;
		
		System.out.println("IMService  ----->  onCreate");
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("IMService  ----->  onStartCommand");

		if (IMClient.shareInstance().haveLogined(getBaseContext())) {
			startConnectThread();
		}
		return START_STICKY;
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		System.out.println("IMService  ----->  onDestroy");

		isRunning = false;
		// 取消连接
		InterruptThread.stopThreads(connectThread, readThread, writeThread);
	}
	
	@Override
	public synchronized void offLine() {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
		}
		if (connectState == ConnectState.OFFLINE) {
			return;
		}
		connectState = ConnectState.OFFLINE;
		
		if (null != heartbeatTool) {
			heartbeatTool.cancelListener();
		}
		
		System.out.println("------------------->   离线  " + Thread.currentThread().getName());
		startConnectThread();
	}
	
	// 启动连接线程.
	private synchronized void startConnectThread() {
		if (connectState == ConnectState.CONNECTING || connectState == ConnectState.CONNECTED) {
			return;
		}
		connectState = ConnectState.CONNECTING;
		
		InterruptThread.stopThreads(connectThread, readThread, writeThread);
		connectThread = new ConnectThread();
		connectThread.start();
	}
	
	// 启动读写线程
	private synchronized void startReadWriteThread(Socket socket) {
		InterruptThread.stopThreads(readThread, writeThread);
		readThread = new ReadThread(socket);
		writeThread = new WriteThread(socket);
		readThread.start();
		writeThread.start();
	}
	
	private class ConnectThread extends InterruptThread {
		
		@Override
		public void run() {
			while (true) {
				if (!isRunning || isStop()) {
					break;
				}
				try {
					System.out.println("启动IM服务");
//					Socket socket = new Socket("192.168.1.182", 6000);
//					Socket socket = new Socket("123.57.81.167", 6969);
					Socket socket = new Socket("192.168.0.121", 6969);
					socket.setSoTimeout(0);
					socket.setReceiveBufferSize(8196);
					socket.setSendBufferSize(8196);
					socket.setTcpNoDelay(true);
					if (socket.isConnected()) {
						heartbeatTool = new IMHeartbeatTool(IMService.this);
						heartbeatTool.startListener();
						startReadWriteThread(socket);
					}
					connectState = ConnectState.CONNECTED;
					
					System.out.println("连接服务器成功" + Thread.currentThread().getName());
					// 向服务端发送验证信息
					IMClient.shareInstance().sendInitMessage(getBaseContext());
					break;
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println("ConnectThread异常   Exception" + e);
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					continue;
				}
			}
		}
	}
	
	private class ReadThread extends InterruptThread {
		
		private final Socket socket;
		
		public ReadThread(Socket socket) {
			super();
			this.socket = socket;
		}

		@Override
		public void run() {
			InputStream is = null;
			try {
				while (true) {
					if (isStop() || !socket.isConnected() || socket.isClosed()) {
						break;
					}
					if (null == is) {
						is = socket.getInputStream();
					}
					// 读取包头
					heartbeatTool.readBuffer(is);
					// 如果是心跳包，直接进入下次循环
					if (heartbeatTool.isHeartbeat()) {
						continue;
					}
					IMProcessMessage.processReadMessage(getBaseContext(), heartbeatTool.getHeadBuffer(), is);
				}
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("ReadThread   Exception" + e);
				offLine();
			} finally {
				IMTool.closeStream(is);
				is = null;
			}

		}
	}
	
	private class WriteThread extends InterruptThread {
		
		private final Socket socket;
		
		public WriteThread(Socket socket) {
			super();
			this.socket = socket;
		}
		
		@Override
		public void run() {
			OutputStream os = null;
			try {
				while (true) {
					if (isStop() || !socket.isConnected() || socket.isClosed()) {
						break;
					}
					if (null == os) {
						os = socket.getOutputStream();
					}
					IMProcessMessage.processSendMessage(getBaseContext(), os);
				}
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("WriteThread   Exception" + e);
//				offLine();
			} finally {
				IMTool.closeStream(os);
				os = null;
			}
		}
	}
}
